home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / gui / gtlayout.lha / Source / LTP_PopupClass.c < prev    next >
C/C++ Source or Header  |  1998-09-09  |  26KB  |  1,285 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. /*****************************************************************************/
  15.  
  16. #include <intuition/classes.h>
  17.  
  18. #include <clib/alib_protos.h>    /* For Coerce/Do/DoSuperMethod */
  19.  
  20. /*****************************************************************************/
  21.  
  22. #include "Assert.h"
  23.  
  24. /*****************************************************************************/
  25.  
  26. #ifdef DO_POPUP_KIND    /* Support code */
  27.  
  28. #define PIF_SingleActive    (1 << 0)
  29. #define PIF_ArrowUp            (1 << 1)
  30. #define PIF_ArrowDown        (1 << 2)
  31.  
  32. STATIC VOID
  33. DrawArrow(
  34.     struct RastPort *    RPort,
  35.     LONG                Left,
  36.     LONG                Top,
  37.     LONG                ArrowWidth,
  38.     LONG                ArrowHeight,
  39.     LONG                Dir)
  40. {
  41.     LONG i,Width,Start,Pos;
  42.  
  43.     for(i = 0 ; i < ArrowHeight ; i++)
  44.     {
  45.         Width = ((ArrowWidth * (i + 1)) / ArrowHeight) & ~1;
  46.  
  47.         if(Width < ArrowWidth)
  48.             Width++;
  49.  
  50.         Start = Left + (ArrowWidth - Width) / 2;
  51.  
  52.         if(Dir < 0)
  53.             Pos = Top + i;
  54.         else
  55.             Pos = Top + ArrowHeight - 1 - i;
  56.  
  57.         LTP_DrawLine(RPort,Start,Pos,Start + Width - 1,Pos);
  58.     }
  59. }
  60.  
  61. STATIC VOID
  62. DrawContainer(
  63.     struct RastPort *    RPort,
  64.     LONG                Left,
  65.     LONG                Top,
  66.     LONG                Width,
  67.     LONG                Height,
  68.     struct GadgetInfo *    GadgetInfo,
  69.     PopInfo *            Info,
  70.     UWORD                Highlight,
  71.     UWORD                Disabled)
  72. {
  73.     LONG Shine,Shadow,Txt,Fill;
  74.     LONG Right;
  75.     UWORD * Pens;
  76.  
  77.     Pens = GadgetInfo->gi_DrInfo->dri_Pens;
  78.  
  79.     if(Highlight)
  80.     {
  81.         Shine    = Pens[SHADOWPEN];
  82.         Shadow    = Pens[SHINEPEN];
  83.         Txt        = Pens[FILLTEXTPEN];
  84.         Fill    = Pens[FILLPEN];
  85.     }
  86.     else
  87.     {
  88.         Shine    = Pens[SHINEPEN];
  89.         Shadow    = Pens[SHADOWPEN];
  90.         Txt        = Pens[TEXTPEN];
  91.         Fill    = Pens[BACKGROUNDPEN];
  92.     }
  93.  
  94.     LTP_SetPens(RPort,Fill,0,JAM1);
  95.  
  96.     if(Info->FrameImage != NULL)
  97.     {
  98.         DrawImageState(RPort,Info->FrameImage,Left,Top,Highlight ? IDS_SELECTED : IDS_NORMAL,GadgetInfo->gi_DrInfo);
  99.     }
  100.     else
  101.     {
  102.         LTP_FillBox(RPort,Left + 2,Top + 1,Width - 4,Height - 2);
  103.         LTP_RenderBevel(RPort,Pens,Left,Top,Width,Height,Highlight,2);
  104.     }
  105.  
  106.     Right = Left + Width - Info->MarkLeft;
  107.  
  108.     LTP_SetAPen(RPort,Shadow);
  109.     LTP_DrawLine(RPort,Right,Top + 2,Right,Top + Height - 3);
  110.  
  111.     LTP_SetAPen(RPort,Shine);
  112.     LTP_DrawLine(RPort,Right + 1,Top + 2,Right + 1,Top + Height - 3);
  113.  
  114.     SetFont(RPort,Info->Font);
  115.     LTP_SetAPen(RPort,Txt);
  116.  
  117.     LTP_DrawAdjustedPicker(RPort,FALSE,Right + 2,Top,Info->PickerWidth,Height,Info->AspectX,Info->AspectY);
  118.  
  119.     LTP_PrintText(RPort,Info->Labels[Info->Active],Info->ActiveLen,Left + 6,Top + Info->LabelTop);
  120.  
  121.     if(Disabled)
  122.         LTP_GhostBox(RPort,Left,Top,Width,Height,Pens[SHADOWPEN]);
  123. }
  124.  
  125. STATIC VOID
  126. DrawOneBox(
  127.     PopInfo *    Info,
  128.     LONG        Top,
  129.     LONG        Index)
  130. {
  131.     struct RastPort    *    RPort;
  132.     LONG                Len;
  133.     LONG                Extra;
  134.     STRPTR                Label;
  135.  
  136.     Label = Info->Labels[Index];
  137.  
  138.     RPort = Info->Window->RPort;
  139.  
  140.     if((Len = strlen(Label)) > Info->MaxLen)
  141.         Len = Info->MaxLen;
  142.  
  143.     if(Info->CheckGlyph)
  144.         Extra = Info->CheckGlyph->Width + 2;
  145.     else
  146.         Extra = 0;
  147.  
  148.     LTP_PrintText(RPort,Label,Len,6 + Extra,Top + Info->LineTop);
  149.  
  150.     if(Extra && Index == Info->InitialActive)
  151.         LTP_DrawCheckGlyph(RPort,6,Top + Info->LineTop,Info->CheckGlyph,Index == Info->LastLabelDrawn);
  152. }
  153.  
  154. STATIC VOID
  155. DrawOneGlyph(
  156.     PopInfo *    Info,
  157.     LONG        Top,
  158.     LONG        Dir,
  159.     UWORD *        Pens)
  160. {
  161.     struct RastPort *RPort;
  162.  
  163.     RPort = Info->Window->RPort;
  164.  
  165.     if(Pens != NULL)
  166.     {
  167.         LTP_SetAPen(RPort,Info->MenuBack);
  168.         LTP_FillBox(RPort,4,Top,Info->SingleWidth,Info->SingleHeight);
  169.         LTP_SetAPen(RPort,Info->MenuText);
  170.     }
  171.  
  172.     DrawArrow(RPort,6,Top + Info->ArrowTop,Info->ArrowWidth,Info->ArrowHeight,Dir);
  173. }
  174.  
  175. STATIC VOID
  176. BoxRender(
  177.     PopInfo *    Info,
  178.     UWORD *        Pens,
  179.     LONG        Active,
  180.     BOOL        FullRefresh,
  181.     BOOL        Highlight,
  182.     LONG        Dir)
  183. {
  184.     struct RastPort *RPort = Info->Window->RPort;
  185.  
  186.     if(FullRefresh)
  187.     {
  188.         LONG Index,Top;
  189.         LONG Width,Height;
  190.  
  191.         LTP_SetPens(RPort,Info->MenuBack,0,JAM1);
  192.  
  193.         Width    = Info->Window->Width;
  194.         Height    = Info->Window->Height;
  195.  
  196.         LTP_FillBox(RPort,2,1,Width - 4,Height - 2);
  197.  
  198.         LTP_SetAPen(RPort,Info->MenuText);
  199.  
  200.         LTP_PolyDraw(RPort,5,
  201.             1,1,
  202.             1,Height - 2,
  203.             0,Height - 2,
  204.             0,0,
  205.             Width - 1,0);
  206.  
  207.         LTP_PolyDraw(RPort,5,
  208.             0,Height - 1,
  209.             Width - 1,Height - 1,
  210.             Width - 1,1,
  211.             Width - 2,1,
  212.             Width - 2,Height - 2);
  213.  
  214.         Index    = Info->TopMost;
  215.         Top        = 2;
  216.         Height    = Info->BoxHeight;
  217.  
  218.         Info->Flags &= ~(PIF_ArrowUp | PIF_ArrowDown);
  219.  
  220.         if(Info->TopMost > 0 && Active != Info->TopMost && Info->BoxLines > 2)
  221.         {
  222.             Info->Flags |= PIF_ArrowUp;
  223.  
  224.             Index    += 1;
  225.             Top        += Info->SingleHeight;
  226.             Height    -= Info->SingleHeight;
  227.         }
  228.  
  229.         if(Info->TopMost + Info->BoxLines < Info->NumLabels && Active != Info->TopMost + Info->BoxLines - 1 && Info->BoxLines > 2)
  230.         {
  231.             Info->Flags |= PIF_ArrowDown;
  232.  
  233.             Height -= Info->SingleHeight;
  234.         }
  235.  
  236.         Info->LastLabelDrawn = Active;    // IMPORTANT: must be set up here to DrawOneBox can find it
  237.  
  238.         for(NULL ; Index < Info->NumLabels && Height > 0 ; Index++, Top += Info->SingleHeight, Height -= Info->SingleHeight)
  239.         {
  240.             if(Index == Active)
  241.             {
  242.                 LTP_SetAPen(RPort,Info->MenuBackSelect);
  243.                 LTP_FillBox(RPort,4,Top,Info->SingleWidth,Info->SingleHeight);
  244.  
  245.                 LTP_SetAPen(RPort,Info->MenuTextSelect);
  246.                 DrawOneBox(Info,Top,Index);
  247.  
  248.                 LTP_SetAPen(RPort,Info->MenuText);
  249.             }
  250.             else
  251.             {
  252.                 DrawOneBox(Info,Top,Index);
  253.             }
  254.         }
  255.  
  256.         if(Info->Flags & PIF_ArrowUp)
  257.             DrawOneGlyph(Info,2,-1,NULL);
  258.  
  259.         if(Info->Flags & PIF_ArrowDown)
  260.             DrawOneGlyph(Info,2 + (Info->BoxLines - 1) * Info->SingleHeight,1,NULL);
  261.  
  262.         Info->LastDrawn = 2 + (Active - Info->TopMost) * Info->SingleHeight;
  263.     }
  264.     else
  265.     {
  266.         if(Info->LastLabelDrawn != -1)
  267.         {
  268.             LONG Top = Info->LastDrawn,Last = Info->LastLabelDrawn;
  269.  
  270.             Info->LastLabelDrawn = -1;
  271.  
  272.             LTP_SetPens(RPort,Info->MenuBack,0,JAM1);
  273.             LTP_FillBox(RPort,4,Top,Info->SingleWidth,Info->SingleHeight);
  274.             LTP_SetAPen(RPort,Info->MenuText);
  275.  
  276.             DrawOneBox(Info,Top,Last);
  277.         }
  278.  
  279.         Info->LastDrawn = -1;
  280.  
  281.         if(Active >= 0)
  282.         {
  283.             LONG Top,NewActive;
  284.  
  285.             NewActive    = Active - Info->TopMost;
  286.             Top            = 2 + NewActive * Info->SingleHeight;
  287.  
  288.             if(Top >= 2 && Top < Info->BoxHeight + 2)
  289.             {
  290.                 LONG Pen;
  291.  
  292.                 if(Dir != 0)
  293.                     Highlight = FALSE;
  294.  
  295.                 if(Highlight)
  296.                 {
  297.                     Pen = Info->MenuBackSelect;
  298.  
  299.                     Info->LastDrawn            = Top;
  300.                     Info->LastLabelDrawn    = Active;
  301.                 }
  302.                 else
  303.                 {
  304.                     Pen = Info->MenuBack;
  305.                 }
  306.  
  307.                 LTP_SetPens(RPort,Pen,0,JAM1);
  308.                 LTP_FillBox(RPort,4,Top,Info->SingleWidth,Info->SingleHeight);
  309.  
  310.                 if(Highlight)
  311.                     Pen = Info->MenuTextSelect;
  312.                 else
  313.                     Pen = Info->MenuText;
  314.  
  315.                 LTP_SetAPen(RPort,Pen);
  316.  
  317.                 if(Dir == 0)
  318.                     DrawOneBox(Info,Top,Active);
  319.                 else
  320.                     DrawOneGlyph(Info,Top,Dir,NULL);
  321.             }
  322.         }
  323.     }
  324. }
  325.  
  326. STATIC ULONG
  327. InputMethod(
  328.     struct IClass *        class,
  329.     struct Gadget *        gadget,
  330.     struct gpInput *    InputInfo)
  331. {
  332.     PopInfo    *Info    = INST_DATA(class,gadget);
  333.     ULONG     Result    = GMR_MEACTIVE;
  334.     BOOL     Done    = FALSE;
  335.     BOOL     Redraw    = FALSE;
  336.  
  337.     if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  338.     {
  339.         UWORD Code = InputInfo->gpi_IEvent->ie_Code;
  340.  
  341.         if(Code == MENUDOWN)
  342.         {
  343.             Result    = GMR_NOREUSE;
  344.             Done    = TRUE;
  345.  
  346.             Info->Active = Info->InitialActive;
  347.         }
  348.         else
  349.         {
  350.             if(Code == SELECTUP)
  351.             {
  352.                 Done = TRUE;
  353.  
  354.                 if(Info->Active < 0)
  355.                 {
  356.                     Result = GMR_NOREUSE;
  357.  
  358.                     Info->Active = Info->InitialActive;
  359.                 }
  360.                 else
  361.                 {
  362.                     LONG Len;
  363.  
  364.                     Result = GMR_NOREUSE | GMR_VERIFY;
  365.  
  366.                     if(Info->Flags & PIF_SingleActive)
  367.                     {
  368.                         LONG Width,Height;
  369.                         LONG x,y;
  370.  
  371.                         x = InputInfo->gpi_Mouse.X;
  372.                         y = InputInfo->gpi_Mouse.Y;
  373.  
  374.                         Width    = gadget->Width;
  375.                         Height    = gadget->Height;
  376.  
  377.                         if(x >= 0 && y >= 0 && x < Width && y < Height)
  378.                         {
  379.                             if(InputInfo->gpi_IEvent->ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  380.                                 Info->Active--;
  381.                             else
  382.                                 Info->Active++;
  383.  
  384.                             if(Info->Active >= Info->NumLabels)
  385.                             {
  386.                                 Info->Active = 0;
  387.                             }
  388.                             else
  389.                             {
  390.                                 if(Info->Active < 0)
  391.                                     Info->Active = Info->NumLabels - 1;
  392.                             }
  393.                         }
  394.                         else
  395.                         {
  396.                             Result = GMR_NOREUSE;
  397.  
  398.                             Info->Active = Info->InitialActive;
  399.                         }
  400.                     }
  401.  
  402.                     Len = strlen(Info->Labels[Info->Active]);
  403.  
  404.                     if(Len > Info->MaxLen)
  405.                         Len = Info->MaxLen;
  406.  
  407.                     Info->ActiveLen = Len;
  408.  
  409.                     (*InputInfo->gpi_Termination) = Info->Active;